#!/usr/bin/env python3
# -*- coding=utf-8 -*-
# 本脚由亁颐堂现任明教教主编写，用于乾颐盾Python课程！
# 教主QQ:605658506
# 亁颐堂官网www.qytang.com
# 教主技术进化论拓展你的技术新边疆
# https://ke.qq.com/course/271956?tuin=24199d8a

from devnet.models import Department, Navbar, Devicedb, DeviceInterface, MonitorInterval
from django.shortcuts import render
from datetime import datetime, timedelta
import numpy as np
from django.http import JsonResponse
from django.contrib.auth.decorators import permission_required


def get_speed_monitor_interval():
    try:
        speed_monitor_interval = MonitorInterval.objects.get(name='speed_interval').interval
    except MonitorInterval.DoesNotExist:
        m = MonitorInterval(name='speed_interval',
                            interval=1)
        m.save()
        speed_monitor_interval = MonitorInterval.objects.get(name='speed_interval').interval
    return speed_monitor_interval


@permission_required('devnet.view_deviceinterface')
def device_monitor_if_speed(request):
    html_title = Department.objects.get(name='admin').departtitle.title
    navbar_list = []
    for navbar in Navbar.objects.all().order_by('id'):
        navbar_list.append([navbar.name, navbar.url])
    active_navbar = '设备监控'
    sidebar_list = []
    for sidebar in Navbar.objects.get(name='设备监控').Sidebar.all().order_by('id'):
        sidebar_list.append([sidebar.name, sidebar.url])
    active_sidebar = '接口速率'
    devices_list = []

    for device in Devicedb.objects.all().order_by('id'):
        devices_list.append({'id': device.id, 'name': device.name})

    current_obj = Devicedb.objects.all().order_by('id')[0]
    current = current_obj.name
    device_id = current_obj.id
    if_list = []
    for interface in current_obj.interface.all():
        if interface.interface_in_bytes.all().order_by('-id')[0].in_bytes and \
                interface.interface_out_bytes.all().order_by('-id')[0].out_bytes and \
                interface.interface_state.all().order_by('-id')[0].state:
            if_dict = {'id': interface.id, 'name': interface.interface_name}
        else:
            continue
        if_list.append(if_dict)

    return render(request, 'devnet_device_monitor_if_speed.html', locals())


@permission_required('devnet.view_deviceinterface')
def device_monitor_if_speed_device(request, device_id):
    html_title = Department.objects.get(name='admin').departtitle.title
    navbar_list = []
    for navbar in Navbar.objects.all().order_by('id'):
        navbar_list.append([navbar.name, navbar.url])
    active_navbar = '设备监控'
    sidebar_list = []
    for sidebar in Navbar.objects.get(name='设备监控').Sidebar.all().order_by('id'):
        sidebar_list.append([sidebar.name, sidebar.url])
    active_sidebar = '接口速率'
    devices_list = []
    for device in Devicedb.objects.all().order_by('id'):
        devices_list.append({'id': device.id, 'name': device.name})

    current_obj = Devicedb.objects.get(id=device_id)
    current = current_obj.name

    if_list = []
    for interface in current_obj.interface.all():
        try:
            if interface.interface_in_bytes.all().order_by('-id')[0].in_bytes and \
                    interface.interface_out_bytes.all().order_by('-id')[0].out_bytes and \
                    interface.interface_state.all().order_by('-id')[0].state:
                if_dict = {'id': interface.id, 'name': interface.interface_name}
            else:
                continue
        except IndexError:
            continue
        if_list.append(if_dict)

    return render(request, 'devnet_device_monitor_if_speed.html', locals())


@permission_required('devnet.view_deviceinterface')
def device_monitor_if_speed_device_ajax(request, interface_id, direction):
    interface_obj = DeviceInterface.objects.get(id=interface_id)
    ifname = interface_obj.interface_name
    bytes_list = []
    time_list = []
    time_strf_list = []
    if direction == 'rx':
        bytes_data = interface_obj.interface_in_bytes.filter(record_datetime__gt=datetime.now() - timedelta(hours=get_speed_monitor_interval()))
        for x in sorted(bytes_data, key=lambda k: k.record_datetime):
            bytes_list.append(x.in_bytes)
            time_list.append(x.record_datetime)
            time_strf_list.append(x.record_datetime.strftime('%H:%M:%S'))

    elif direction == 'tx':
        bytes_data = interface_obj.interface_out_bytes.filter(record_datetime__gt=datetime.now() - timedelta(hours=get_speed_monitor_interval()))

        for x in sorted(bytes_data, key=lambda k: k.record_datetime):
            bytes_list.append(x.out_bytes)
            time_list.append(x.record_datetime)
            time_strf_list.append(x.record_datetime.strftime('%H:%M:%S'))

    # numpy的diff计算列表的差值
    # np.diff([x for x in range(5)])
    # array([1, 1, 1, 1])
    # 通过这种方式获取两次获取的字节数的差值
    diff_if_bytes_list = list(np.diff(bytes_list))

    # 计算两次时间对象的秒数的差值, np的多态太牛逼了
    diff_record_time_list = [x.seconds for x in np.diff(time_list)]

    # 计算速率
    # * 8 得到bit数
    # /1000 计算kb
    # / x[1] 计算kbps
    # round(x, 2) 保留两位小数
    # zip把字节差列表 和 时间差列表 压到一起

    # 过滤负数
    zip_list = []
    for z in zip(diff_if_bytes_list, diff_record_time_list):
        if z[0] < 0:
            continue
        else:
            zip_list.append(z)
    speed_data = list(map(lambda x: round(((x[0] * 8) / (1000 * x[1])), 2), zip_list))
    speed_time = time_strf_list[1:]
    return JsonResponse({"ifname": ifname, "speed_data": speed_data, "speed_time": speed_time})
